package exp3;

public class MyCircleArrayQueue<T> implements MyQueue<T> {
    private T[] queue;
    private int size;
    private int headMarker, tailMarker;
    private int defaultSize = 5;

    public MyCircleArrayQueue() {
        queue = (T[]) new Object[defaultSize];
        size = 0;
        headMarker = -1;
        tailMarker = 0;
    }

    @Override
    public void offer (T value) {
        headMarker++;
        headMarker %= defaultSize;
        if (size >= defaultSize) {
            kuoRong();
        }
        queue[headMarker] = value;
        size++;
    }

    @Override
    public void poll() throws Exception{
        if (size == 0) {
            throw new Exception("Empty Stack");
        } else {
            tailMarker++;
            tailMarker %= defaultSize;
            size--;
        }
    }

    @Override
    public T peek() throws Exception{
        if (size == 0) {
            throw new Exception("Empty Stack");
        } else {
            return queue[headMarker % defaultSize];
        }
    }

    @Override
    public String toString() {
        StringBuilder str = new StringBuilder("[");
        if (size > 0) {
            str.append(queue[headMarker]);
            for (int i = headMarker - 1; i >= tailMarker; i--) {
                if (i == -1) {
                    i = defaultSize - 1;
                }
                str.append(", ");
                str.append(queue[i]);
            }
        }
        str.append("]");
        return str.toString();
    }

    private void kuoRong() {
        defaultSize *= 2;
        T[] queue2 = (T[]) new Object[defaultSize];
        if (headMarker >= defaultSize) {
            int j = 0;
            for (int i = tailMarker; i < defaultSize / 2; i++) {
                queue2[j] = queue[i];
                j++;
            }
            for (int i = 0; i < headMarker; i++) {
                queue2[j] = queue[i];
                j++;
            }
        }
        queue = queue2;
    }

    public static void main(String[] args) {
        MyArrayQueue<Integer> queue = new MyArrayQueue<>();
        for (int i = 0; i < 5; i++) {
            queue.offer(i);
            System.out.println(queue);
        }
        queue.poll();
        System.out.println(queue);
        queue.offer(10);
        System.out.println(queue);
        queue.offer(20);
        System.out.println(queue);
    }
}
